package com.cpsdna.module;

import com.cpsdna.bean.document.Document;
import com.cpsdna.bean.firm.Firm;
import com.cpsdna.bean.user.OperationLog;
import com.cpsdna.bean.user.User;
import com.cpsdna.util.SessionManger;
import eu.bitwalker.useragentutils.UserAgent;
import org.nutz.dao.Cnd;
import org.nutz.dao.sql.Criteria;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Files;
import org.nutz.lang.Lang;
import org.nutz.lang.Strings;
import org.nutz.lang.Times;
import org.nutz.lang.random.R;
import org.nutz.log.Log;
import org.nutz.log.Logs;
import org.nutz.mvc.Mvcs;
import org.nutz.mvc.annotation.*;
import org.nutz.mvc.filter.CheckSession;
import org.nutz.mvc.upload.TempFile;
import org.nutz.service.EntityService;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 七牛图片资源管理
 * Created by Jianghao on 2017/1/7.
 */
@IocBean(fields = {"dao"})
@Ok("json:{locked:'password|salt', ignoreNull:true}")
@Fail("http:500")
@At("/document")
public class DocumentModule extends EntityService<Document> {

//    @Inject("java:$conf.get('qiniu.accessKey')")
//    private String ACCESSKEY;
//    @Inject("java:$conf.get('qiniu.secretKey')")
//    private String SECRETKEY;
//    @Inject("java:$conf.get('qiniu.bucketName')")
//    private String BUCKETNAME;
//    @Inject("java:$conf.get('qiniu.url')")
//    private String URL;

    @Inject("java:$conf.get('file.path')")
    private String FILE_PATH;
    @Inject("java:$conf.get('file.url')")
    private String FILE_URL;

    private static final Log log = Logs.get();

    @POST
    @At("/upload")
    @Ok("redirect:${obj}")
    @AdaptBy(args = {"ioc:upload"})
    @Filters(@By(type = CheckSession.class, args = {User.USER_SESSION_KEY, "/login.htm?returnUrl=/document/upload.htm"}))
    public String upload(@Param("file") TempFile[] tfs) {

        Integer firmId = Strings.isBlank(Mvcs.getReq().getParameter("firmId")) ? 0 : Integer.parseInt(Mvcs.getReq()
                .getParameter("firmId"));

        try {
            for (int i = 0; i < tfs.length; i++) {

                String uuid = R.UU32();
                String fullPathName = FILE_PATH + uuid + Files.getSuffix(tfs[i].getFile());
                tfs[i].write(fullPathName);
                Files.write(fullPathName, tfs[i].getInputStream());
                Document document = new Document();
                document.setFileDownloadUrl(FILE_URL + uuid + Files.getSuffix(tfs[i].getFile()));
                document.setDocumentName(tfs[i].getSubmittedFileName());
                document.setFileHash(Lang.sha1(tfs[i].getFile()));
                document.setFileType(tfs[i].getContentType());
                document.setFileSize(tfs[i].getSize());
                document.setFirmId(firmId);
                document.setFileUploadTime(Times.now());
                dao().insert(document);
                log.info("上传资源: " + tfs[i].getName() + Files.getSuffix(tfs[i].getFile()));
                tfs[i].delete();
            }
            Lang.exec("chmod -R 777 " + FILE_PATH, null, null);
            return "/document/upload.htm?alert=success";
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return "/document/upload.htm?alert=error";
        }
    }

//    @POST
//    @At("/document/upload")
//    @Ok("redirect:${obj}")
//    @AdaptBy(args = {"ioc:upload"})
//    public String upload(@Param("file") TempFile[] tfs) {
//
//        try {
//            for (int i = 0; i < tfs.length; i++) {
//                BufferedImage image = Images.read(tfs[i].getFile());
//                String extensionName = Files.getSuffixName(tfs[i].getFile()).toLowerCase();
//                ByteArrayOutputStream out = new ByteArrayOutputStream();
//                Images.write(image, extensionName, out);
//                Zone z = Zone.autoZone();
//                Configuration c = new Configuration(z);
//                Auth auth = Auth.create(ACCESSKEY, SECRETKEY);
//                UploadManager uploadManager = new UploadManager(c);
//                uploadManager.put(out.toByteArray(), "images/" + R.UU32() + "." + extensionName, auth.uploadToken(BUCKETNAME));
//                log.info("上传图片: " + Files.getMajorName(tfs[i].getFile()) + Files.getSuffix(tfs[i].getFile()));
//            }
//            return "/resource/upload.htm?alert=success";
//        } catch (QiniuException e) {
//            Response r = e.response;
//            log.error("上传资源到七牛服务器失败：" + r);
//            return "/resource/upload.htm?alert=error";
//        }
//    }

    @GET
    @At("/upload")
    @Ok("beetl:/document/upload.btl")
    @Filters(@By(type = CheckSession.class, args = {User.USER_SESSION_KEY, "/login.htm?returnUrl=/document/upload.htm"}))
    public Map<String, Object> upload() throws IOException {

        Map<String, Object> map = new HashMap<String, Object>();
        map.put("user", SessionManger.getCurrentUser(Mvcs.getReq()));
        map.put("firmList", dao().query(Firm.class, null));
        return map;
    }

    @GET
    @At("/list")
    @Ok("beetl:/document/list.btl")
    @Filters(@By(type = CheckSession.class, args = {User.USER_SESSION_KEY, "/login.htm?returnUrl=/document/list.htm"}))
    public Map<String, Object> list() throws IOException {
        Map<String, Object> map = new HashMap<String, Object>();
        User user = SessionManger.getCurrentUser(Mvcs.getReq());
        map.put("user", user);

        Criteria cri = Cnd.cri();
        if (!Strings.equals(user.getUserGroup(), "{1}"))
            cri.where().and(Cnd.exps("firm_id", "=", user.getFirmId()).or("firm_id", "=", 1));
        cri.getOrderBy().desc("file_upload_time");
        List<Document> documentList = dao().query(Document.class, cri);
        dao().fetchLinks(documentList, "firm");
        map.put("documentList", documentList);
        return map;
    }

//    @GET
//    @At("/resource/list")
//    @Ok("beetl:/resource/list.btl")
//    @RequiresAuthentication
//    public Map<String, Object> list() throws IOException {
//
//        Map<String, Object> map = new HashMap<String, Object>();
//        User user = Util.getCurrentUser(Mvcs.getReq());
//        map.put("user", user);
//        Auth auth = Auth.create(ACCESSKEY, SECRETKEY);
//        Zone z = Zone.zone0();
//        Configuration c = new Configuration(z);
//        BucketManager bucketManager = new BucketManager(auth, c);
//        List<Resource> resourceList = new ArrayList<Resource>();
//        try {
//            FileListing fileListing = bucketManager.listFiles(BUCKETNAME, "images/", null, 1000, null);
//            FileInfo[] items = fileListing.items;
//            for (FileInfo fileInfo : items) {
//                Resource resource = new Resource();
//                resource.setFileSize(new java.text.DecimalFormat("#.##").format(fileInfo.fsize / 1024) + " KB");
//                resource.setFileName(URL + fileInfo.key);
//                resource.setHash(fileInfo.hash);
//                resource.setMimeType(fileInfo.mimeType);
//                resource.setPutTime(DateUtil.timestampToString(fileInfo.putTime / 10000000, DateUtil.FORMAT_ONE));
//                resourceList.add(resource);
//            }
//        } catch (QiniuException e) {
//            Response r = e.response;
//            log.error("获取七牛资源列表失败：" + r);
//        }
//        map.put("resourceList", resourceList);
//        return map;
//    }

//    @At("/resource/del")
//    @Ok("redirect:${obj}")
//    public String del(@Param("key") String key) {
//
//        Auth auth = Auth.create(ACCESSKEY, SECRETKEY);
//        Zone z = Zone.zone0();
//        Configuration c = new Configuration(z);
//        BucketManager bucketManager = new BucketManager(auth, c);
//        try {
//            bucketManager.delete(BUCKETNAME, key.replaceAll(URL, ""));
//            return "/resource/list.htm?alert=success";
//        } catch (QiniuException e) {
//            Response r = e.response;
//            log.error("删除七牛资源失败：" + r);
//            return "/resource/list.htm?alert=success";
//        }
//    }

    @GET
    @At("/assign")
    @Ok("beetl:/document/assign.btl")
    @Filters(@By(type = CheckSession.class, args = {User.USER_SESSION_KEY, "/login.htm?returnUrl=/document/assign.htm"}))
    public Map<String, Object> add() throws IOException {

        Map<String, Object> map = new HashMap<String, Object>();
        map.put("user", SessionManger.getCurrentUser(Mvcs.getReq()));
        Document document = dao().fetch(Document.class, Cnd.where("document_id", "=", Mvcs.getReq().getParameter
                ("documentId")));
        if (Lang.isEmpty(document))
            Mvcs.getResp().sendRedirect("/error/404.html");
        map.put("document", document);
        map.put("firmList", dao().query(Firm.class, Cnd.where("firm_id", ">", 1)));
        return map;
    }

    @POST
    @At("/assign")
    @Ok("redirect:${obj}")
    @Filters(@By(type = CheckSession.class, args = {User.USER_SESSION_KEY, "/login.htm?returnUrl=/document/add.htm"}))
    public String add(@Param("documentId") String documentId, @Param("firmId") String firmId) {


        Document document = dao().fetch(Document.class, Cnd.where("document_id", "=", documentId));
        if (Lang.isEmpty(document))
            return "/error/404.html";
        Firm firm = dao().fetch(Firm.class, Cnd.where("firm_id", "=", firmId));
        if (Lang.isEmpty(firm))
            return "/error/404.html";
        Document doc = dao().fetch(Document.class, Cnd.where("file_hash", "=", document.getFileHash()).and("firm_id",
                "=", firm.getFirmId()));
        if (Lang.isEmpty(doc)) {

            try {

                document.setFirmId(firm.getFirmId());
                document.setFileUploadTime(Times.now());
                document.setDocumentId(null);
                dao().insert(document);
                User user = SessionManger.getCurrentUser(Mvcs.getReq());
                UserAgent userAgent = UserAgent.parseUserAgentString(Mvcs.getReq().getHeader("User-Agent"));
                OperationLog operationLog = new OperationLog(user.getUserId(), "分配文档" + document.getDocumentId()
                        + "给" + firm.getFirmId(), Lang
                        .getIP
                                (Mvcs.getReq
                                        ()),
                        "操作系统版本（"
                                + userAgent
                                .getOperatingSystem() + "）；浏览器版本（" + userAgent.getBrowser() + "-" + userAgent
                                .getBrowserVersion() + "）", Times.now());
                dao().insert(operationLog);
                return "/document/assign.htm?alert=success&documentId=" + documentId;
            } catch (Exception e) {
                log.error(e.getMessage(), e);
                return "/document/assign.htm?alert=error&documentId=" + documentId;
            }
        }
        return "/document/assign.htm?alert=error&documentId=" + documentId;
    }

    @At("/del")
    @Ok("redirect:${obj}")
    @Filters(@By(type = CheckSession.class, args = {User.USER_SESSION_KEY, "/login.htm?returnUrl=/document/list.htm"}))
    public String del(@Param("documentId") String documentId) {

        User user = SessionManger.getCurrentUser(Mvcs.getReq());
        if (!Strings.equals(user.getUserGroup(), "{1}"))
            return "/error/403.html";

        Document document = dao().fetch(Document.class, Cnd.where("document_id", "=", documentId));
        if (Lang.isEmpty(document))
            return "/error/404.html";
        else {
            try {
                UserAgent userAgent = UserAgent.parseUserAgentString(Mvcs.getReq().getHeader("User-Agent"));
                OperationLog operationLog = new OperationLog(user.getUserId(), "删除文档" + document.getDocumentName(), Lang
                        .getIP
                                (Mvcs.getReq
                                        ()),
                        "操作系统版本（"
                                + userAgent
                                .getOperatingSystem() + "）；浏览器版本（" + userAgent.getBrowser() + "-" + userAgent
                                .getBrowserVersion() + "）", Times.now());
                dao().insert(operationLog);
                dao().delete(document);
                return "/document/list.htm?alert=success";
            } catch (Exception e) {
                log.error(e.getMessage(), e);
                return "/document/list.htm?alert=error";
            }
        }
    }
}